﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PanelLoading : PanelCommon {

   // [HideInInspector]
    [SerializeField]
    float m_Radius = 10;
    public float radius
    {
        get
        {
            return m_Radius;
        }
        set
        {
            if (m_Radius != value)
            {
                RestartAnim();
            }
            m_Radius = value;
        }
    }

    [SerializeField]
    AnimationCurve m_SpeedCurve;

    /// <summary>
    /// 转一圈的周期时间
    /// </summary>
    [SerializeField]
    float m_CycleTime = 2;

    [SerializeField]
    Transform m_Center;

    /// <summary>
    /// 节点数量
    /// </summary>
   // [HideInInspector]
    [SerializeField]
    int m_NodesCount = 5;
    public int nodesCount
    {
        get
        {
            return this.m_NodesCount;
        }
        set
        {
            if (m_NodesCount != value)
            {
                RestartAnim();
            }
            m_NodesCount = value;
        }
    }

    /// <summary>
    /// 节点间隔
    /// </summary>
  //  [HideInInspector]
    [SerializeField]
    float m_NodeInterval = 0.1f;
    public float nodeInterval
    {
        get
        {
            return this.m_NodeInterval;
        }
        set
        {
            if(m_NodeInterval != value)
            {
                RestartAnim();
            }
            m_NodeInterval = value;
        }
    }
    /// <summary>
    /// 节点缩放递减率
    /// </summary>
   // [HideInInspector]
    [SerializeField]
    float m_NodeScaleDiminishing = 0.9f;
    public float nodeScaleDiminishing
    {
        get
        {
            return this.m_NodeScaleDiminishing;
        }
        set
        {
            if (m_NodeScaleDiminishing != value)
            {
                RestartAnim();
            }
            m_NodeScaleDiminishing = value;
        }
    }

    [SerializeField]
    float errorAllow = 0.02f;

 //   static bool m_Showing;
    float m_CurAngle;
    Transform m_NodesParent;

    float m_LifeTime = 10;

    [SerializeField]
    Transform nodePref;

    public override void Awake()
    {
        nodePref.gameObject.SetActive(false);
        m_NodesParent = new UnityEngine.GameObject("NodesParent").transform;
        m_NodesParent.SetParent(transform);
        m_NodesParent.transform.localPosition = Vector3.zero;
        
    }

    public override void Start()
    {
        StartCoroutine(PlayAnim());
    }

    public void SetMaxWaitTime(float time)
    {
        m_LifeTime = time;

        var selfDes = GetComponent<DelayDestroy>();
        if (selfDes == null) selfDes = gameObject.AddComponent<DelayDestroy>();
        selfDes.lifeTime = m_LifeTime;
    }

    static PanelLoading m_Instance;
    static PanelLoading Instance
    {
        get
        {
            if(m_Instance == null)
            {
                if (Game.Instance == null)
                    return null;
                
                Transform parent = Game.Instance.transform;
              
                var pref = GameResourceManager.Load<PanelLoading>(ViewPath.uiLoading);
                m_Instance = Instantiate<PanelLoading>(pref, parent);
                m_Instance.layer = 150;
            }
            return m_Instance;
        }
    }

    public static bool InstanceIsNull()
    {
        return m_Instance == null;
    }

    public static void Show(float maxWaitTime)
    {
        if(Instance)
            Instance.SetMaxWaitTime(maxWaitTime);
        //if(Game.Instance != null)
        //{
        //    var nav = Game.Instance.GetActiveSceneNav();
        //    if (nav)
        //    {
        //        var loading = nav.LoadDisplay<LoadingDisplayController>(false);
        //        loading.DeletePreUI = false;
        //        loading.SetMaxWaitTime(maxWaitTime);
        //      //  m_Showing = true;
        //    }
        //}
    }
    
    public static void Hide()
    {
        if(m_Instance)
            Destroy(m_Instance.gameObject);
        //if (Game.Instance != null)
        //{
        //    var nav = Game.Instance.GetActiveSceneNav();
        //    if (nav)
        //    {
        //        var loading = nav.FindDisplay<LoadingDisplayController>();
        //        if (loading)
        //        {
        //            loading.GoBack();
        //        //    m_Showing = false;
        //        }
        //    }
        //}

    }

    void RestartAnim()
    {
        if (!Application.isPlaying)
            return;
        
        StopAllCoroutines();
        GameDebug.Log("Restart!!");

        StartCoroutine(PlayAnim());
    }

  //  Coroutine animCoroutine;
    IEnumerator PlayAnim()
    {
        for (int i = 0; i < m_NodesParent.childCount; i++)
        {
            Destroy(m_NodesParent.GetChild(i).gameObject);
        }

        Vector3 startPos = GetStartPoint(this.m_Center.position, this.m_Radius);

        List<Transform> nodes = new List<Transform>();
        for (int i = 0; i < m_NodesCount; i++)
        {
            Transform node = Instantiate(nodePref, m_NodesParent);
            node.transform.position = startPos;
            node.transform.localScale = Mathf.Pow(m_NodeScaleDiminishing,i) * Vector3.one;
            node.transform.SetAsFirstSibling();
            node.name = i.ToString();
            nodes.Add(node);
        }
        yield return 0;

        float timer = Time.realtimeSinceStartup;

        int index = 0;
        while (index < nodes.Count)
        {
            if (Time.realtimeSinceStartup > timer + this.m_NodeInterval)
            {
                //计算误差
                float delta = Time.realtimeSinceStartup - timer;
               // GameDebug.Log("delta:" + delta + "  timer:"+ timer+ "   Time.realtimeSinceStartup:" + Time.realtimeSinceStartup);
                float error = Mathf.Abs(delta - this.m_NodeInterval);
                if (error > errorAllow) // m_NodeInterval /6)
                {
                    //误差过大重新播放动画
                    RestartAnim();
                    GameDebug.Log("uiloading over time restart!  error:" + error);
                    yield break;
                }

                StartCoroutine(NodeAnim(nodes[index]));
               // GameDebug.Log("nodes[index]:" + nodes[index].name + "  start :" + Time.realtimeSinceStartup);
                index++;
                timer = Time.realtimeSinceStartup ;
            }
            yield return new WaitForEndOfFrame();
        }

    }

    IEnumerator NodeAnim(Transform node)
    {           
        node.gameObject.SetActive(true);

        Vector3 startPos = GetStartPoint(this.m_Center.position, this.m_Radius);

        float timer = 0;
        while (true)
        {
            timer += Time.deltaTime;
            yield return null;

            timer %= m_CycleTime;
            float x = timer / m_CycleTime;
            float y = m_SpeedCurve.Evaluate(x);

            m_CurAngle = y * 360;
            node.position = ClockwiseRotateAround(startPos, this.m_Center.position, m_CurAngle);
        }
    }

    Vector3 GetStartPoint(Vector3 center,float radius)
    {
        return center + Vector3.up * radius;
    }

    /// <summary>
    /// 顺时针旋转
    /// </summary>
    /// <param name="trans"></param>
    /// <param name="center"></param>
    /// <param name="angle"></param>
    Vector3 ClockwiseRotateAround(Vector3 pos,Vector3 center,float angle)
    {
        Vector3 p = pos - center;
        Quaternion m = Quaternion.AngleAxis(angle, Vector3.back);
        return center + m * p;
    }


    //protected override void GoBackToDisplay()
    //{

    //}

    //public new void GoBack()
    //{
    //    m_Controller.parentNav.GoBackToPreDC();
    //}

}
